package cn.t.service.user;


import cn.t.core.exception.BizException;
import cn.t.core.mode.YesNoEnum;
import cn.t.core.service.ServiceImpl;
import cn.t.core.enums.base.BaseStatusEnum;
import cn.t.core.enums.base.CommonError;
import cn.t.model.user.ParticipantInfoDO;
import cn.t.model.user.ParticipantRoleDO;
import cn.t.model.user.RoleFirmDO;
import cn.t.model.user.RoleInfoDO;
import cn.t.model.user.UserInfoDO;
import cn.t.repository.user.ParticipantRoleRepository;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 参与者和角色关联表领域服务
 *
 * @author l
 */
@Slf4j
@Service
@AllArgsConstructor
public class ParticipantRoleService extends ServiceImpl<ParticipantRoleDO, ParticipantRoleRepository> {


    public List<ParticipantRoleDO> findMenuByParticipantId(Long participantId) {
        return repository.findMenuByParticipantId(participantId);
    }

    public List<ParticipantRoleDO> findAllByParticipantId(Long participantId) {
        return repository.findAllByParticipantId(participantId);
    }
    public List<ParticipantRoleDO> findAllByParticipantIdIgnoreDisable(Long participantId) {
        return repository.findAllByParticipantIdIgnoreDisable(participantId);
    }

    public List<ParticipantRoleDO> findMetalIssueByParticipantId(Long participantId) {
        return repository.findMetalIssueByParticipantId(participantId);
    }

    public List<String> findEmailAddressByParticipantId(Long participantId, Long firmId){
        return repository.findEmailAddressByParticipantId(participantId,firmId);
    }

    public List<ParticipantRoleDO> findMetalReplenishByParticipantId(Long participantId) {
        return repository.findMetalReplenishByParticipantId(participantId);
    }

    public Boolean removeMenuByParticipantId(Long participantId) {
        return repository.removeByParticipantId(participantId);
    }

    public boolean removeByParticipantId(Long participantId) {
        return repository.removeByParticipantId(participantId);
    }

    public List<ParticipantRoleDO> findByRoleId(Long roleId) {
        ParticipantRoleDO template = new ParticipantRoleDO();
        template.setRoleId(roleId);
        template.setStatus(String.valueOf(BaseStatusEnum.AVAILABLE.getCode()));
        template.setIsDeleted(YesNoEnum.FALSE);

        return repository.findByModel(template, 0, 10000, null, null);

    }

    public List<ParticipantRoleDO> findByRoleIds(List<Long> roleIds) {
        ParticipantRoleDO template = new ParticipantRoleDO();
        template.setRoleIds(roleIds);
        return repository.findByModel(template, 0, 10000, null, null);

    }

    public List<ParticipantRoleDO> createAnonymousRole(ParticipantInfoDO participantInfo) {
        List<RoleInfoDO> anonymousRole = roleInfoService.createAnonymousRole(participantInfo);
        List<ParticipantRoleDO> results = new ArrayList<>();

        for (RoleInfoDO roleInfoDTO : anonymousRole) {
            ParticipantRoleDO participantRole = new ParticipantRoleDO();
            participantRole.setParticipantId(participantInfo.getId());
            participantRole.setUserId(participantInfo.getUserId());
            participantRole.setRoleId(roleInfoDTO.getId());
            participantRole.setStatus(String.valueOf(BaseStatusEnum.AVAILABLE.getCode()));

            Long participantRoleId = repository.addAndReturnId(participantRole);
            participantRole.setId(participantRoleId);
            results.add(participantRole);
        }

        return results;
    }

    public void deleteRoleByUserId(Long userId) {
        List<ParticipantInfoDO> participantInfoList = participantInfoService.findByUserId(userId);
        if (participantInfoList == null || participantInfoList.isEmpty()) {
            return;
        }
        participantInfoList.forEach(participantInfo -> {
            deleteAnonymousRoleByParticipantId(participantInfo.getId());
            deleteByParticipantId(participantInfo.getId());
        });

    }

    private void deleteByParticipantId(Long participantId) {
        repository.deleteByParticipantId(participantId);
    }
    public void deleteParticipantRoleByRoleId(Long roleId,Long firmId) {
        repository.deleteParticipantRoleByRoleId(roleId,firmId);
    }

    public void deleteAnonymousRoleByParticipantId(Long participantId) {
        List<RoleInfoDO> anonymousRoleList = roleInfoService.findAnonymousRoleByParticipantId(participantId);
        if (anonymousRoleList == null || anonymousRoleList.isEmpty()) {
            return;
        }
        for (RoleInfoDO roleInfoDTO : anonymousRoleList) {
            roleInfoService.deleteRoleById(roleInfoDTO.getId());
        }
    }



    public Map<Long, ParticipantInfoDO> addRole(UserInfoDO userInfoDO, RoleInfoDO roleInfoDO, Map<Long, ParticipantInfoDO> firmMap) {
        List<RoleFirmDO> roleFirmList = roleFirmService.findByRoleId(roleInfoDO.getId());
        if (CollectionUtils.isEmpty(roleFirmList)) {
            String errorMessage = String.format("指定的角色未绑定公司 roleId=%d roleName=%s", roleInfoDO.getId(), roleInfoDO.getRoleName());
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        }

        for (RoleFirmDO roleFirmDO : roleFirmList) {
            if (!firmMap.containsKey(roleFirmDO.getFirmId())) {
                firmMap.put(roleFirmDO.getFirmId(), participantInfoService.getOrAdd(userInfoDO.getId(), userInfoDO.getIndividualId(), roleFirmDO.getFirmId()));
            }

            ParticipantRoleDO participantRoleDO = new ParticipantRoleDO();
            participantRoleDO.setUserId(userInfoDO.getId());
            participantRoleDO.setParticipantId(firmMap.get(roleFirmDO.getFirmId()).getId());
            participantRoleDO.setRoleId(roleFirmDO.getRoleId());
            participantRoleDO.setStatus(String.valueOf(BaseStatusEnum.AVAILABLE.getCode()));

            add(participantRoleDO);
        }

        return firmMap;
    }

    public Boolean deleteByRoleId(Long roleId) {
        return repository.deleteByRoleId(roleId);
    }

    public void disableRoleByUserId(Long userId) {
        repository.disableRoleByUserId(userId);
    }

    public void enableRoleByUserId(Long userId) {
        repository.enableRoleByUserId(userId);
    }


    @Autowired
    private RoleFirmService roleFirmService;


    @Autowired
    private RoleInfoService roleInfoService;

    @Autowired
    private ParticipantInfoService participantInfoService;



}
